import { CanActivate, ExecutionContext, ForbiddenException, UnauthorizedException, Logger, Injectable } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { PERMISSION_KEY, ADMIN_ROLE_NAME } from "src/constant";

@Injectable()
export class RolesGuard implements CanActivate {
    private readonly logger = new Logger(RolesGuard.name);

    constructor(private reflector: Reflector) {}

    static verifyUser(user: RequsetUser, permission: string[]) {
        if (user.roles.includes(ADMIN_ROLE_NAME)) return true;

        if (permission.some((code) => user.permissions.includes(code))) return true;

        return false;
    }

    async canActivate(context: ExecutionContext) {
        const user: RequsetUser = context.switchToHttp().getRequest()?.user || context.switchToWs().getClient()?.user;

        const permission = this.reflector.getAllAndOverride<string[] | undefined>(PERMISSION_KEY, [
            context.getHandler(),
            context.getClass(),
        ]);

        if (!permission) return true;

        if (!user) throw new UnauthorizedException();

        if (!RolesGuard.verifyUser(user, permission)) throw new ForbiddenException("权限不足!");

        return true;
    }
}
